package com.info33.platform.business.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.info33.platform.business.app.dao.AppRoleUserDao;
import com.info33.platform.business.app.entity.AppRoleUser;
import com.info33.platform.business.app.service.AppRoleUserService;
import com.info33.platform.business.app.vo.AppRoleUserVO;
import com.info33.platform.common.constant.TableConstant;
import com.info33.platform.common.exception.TransactionalException;
import com.info33.platform.common.mvc.vo.Result;
import com.info33.platform.system.vo.SysUserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author admin
 */
@Service
public class AppRoleUserServiceImpl extends ServiceImpl<AppRoleUserDao, AppRoleUser> implements AppRoleUserService {

    @Autowired
    private AppRoleUserDao appRoleUserDao;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void pcBind(Long uid, List<Long> ids) {
        if (ObjectUtils.isEmpty(ids)) {
            return;
        }
        // 先清除所有旧用户身份信息
        List<Object> removeList = appRoleUserDao.selectObjs(new QueryWrapper<AppRoleUser>()
                .select(TableConstant.ID)
                .eq("user_id", uid)
                .gt("role_id", 100));
        if (!ObjectUtils.isEmpty(removeList)
                && Boolean.FALSE.equals(this.removeByIds(removeList.stream().map(l -> Long.parseLong(l.toString())).collect(Collectors.toList())))) {
            throw new TransactionalException();
        }
        List<AppRoleUser> saveList = new ArrayList<>();
        ids.forEach(l -> {
            AppRoleUser entity = new AppRoleUser();
            entity.setRoleId(l);
            entity.setUserId(uid);
            saveList.add(entity);
        });
        if (!ObjectUtils.isEmpty(saveList)
                && Boolean.FALSE.equals(this.saveBatch(saveList))) {
            throw new TransactionalException();
        }
    }

    @Override
    public Result<Object> appSwitch(Long id, SysUserVO currentUser) {
        AppRoleUserVO old = appRoleUserDao.checkPrincipal(id);
        if (Boolean.FALSE.equals(old.getValid())) {
            return Result.error(old.getRoleVO().getName() + " 角色已失效，无法设置为主要角色");
        }
        if (Boolean.TRUE.equals(old.getPrincipal())) {
            return Result.ok(old.getRoleVO().getName() + " 已是主要角色");
        }
        // 将选中的角色切换为主要角色
        AppRoleUser entity = new AppRoleUser();
        entity.setPrincipal(Boolean.TRUE);
        entity.setId(id);
        if (appRoleUserDao.updateById(entity) != 1) {
            throw new TransactionalException();
        }
        // 将其它角色切换为非主要角色
        List<AppRoleUser> oldList = appRoleUserDao.selectList(new QueryWrapper<AppRoleUser>()
                .select(TableConstant.ID, "0 AS principal")
                .eq("user_id", currentUser.getAppTenantUserVO().getId())
                .eq("principal", Boolean.TRUE));
        if (!ObjectUtils.isEmpty(oldList)
                && Boolean.FALSE.equals(this.updateBatchById(oldList))) {
            return Result.error(Result.RESULT_ERROR_PUBLIC_MSG);
        }
        return Result.ok();
    }

    @Override
    @Transactional(propagation = Propagation.MANDATORY, rollbackFor = Exception.class)
    public void addOneInfo(Long id, Long rid, Boolean principal, Boolean valid) {
        AppRoleUser entity = new AppRoleUser();
        entity.setUserId(id);
        entity.setRoleId(rid);
        entity.setPrincipal(ObjectUtils.isEmpty(principal) ? Boolean.FALSE : principal);
        entity.setValid(ObjectUtils.isEmpty(valid) ? Boolean.TRUE : valid);

        AppRoleUser old = this.getOne(new QueryWrapper<AppRoleUser>()
                .eq("user_id", id)
                .eq("role_id", rid));
        if (!ObjectUtils.isEmpty(old)) {
            if (old.getPrincipal().equals(entity.getPrincipal())
                    && old.getValid().equals(entity.getValid())) {
                return;
            }
            entity.setId(old.getId());
        }

        if (Boolean.FALSE.equals(this.saveOrUpdate(entity))) {
            throw new TransactionalException();
        }
        // 新增身份，将其他身份设置为未选择状态
        if (ObjectUtils.isEmpty(principal) || Boolean.FALSE.equals(principal)) {
            return;
        }
        List<AppRoleUser> others = appRoleUserDao.selectList(new QueryWrapper<AppRoleUser>()
                .select(TableConstant.ID, "0 AS principal")
                .eq("user_id", id)
                .ne("role_id", rid)
                .eq("principal", Boolean.TRUE));
        if (!ObjectUtils.isEmpty(others)
                && Boolean.FALSE.equals(this.updateBatchById(others))) {
            throw new TransactionalException();
        }
    }

    @Override
    public void removeOneInfo(Long uid, Long rid) {
        AppRoleUser old = this.getOne(new QueryWrapper<AppRoleUser>()
                .eq("user_id", uid)
                .eq("role_id", rid));
        if (ObjectUtils.isEmpty(old) || old.getValid().equals(Boolean.FALSE)) {
            return;
        }
        AppRoleUser update = new AppRoleUser();
        update.setId(old.getId());
        update.setValid(Boolean.FALSE);
        if (Boolean.FALSE.equals(this.updateById(update))) {
            throw new TransactionalException();
        }
    }
}